/*
**    Copyright (C) 2003-2011 Institute for Systems Biology
**                            Seattle, Washington, USA.
**
**    This library is free software; you can redistribute it and/or
**    modify it under the terms of the GNU Lesser General Public
**    License as published by the Free Software Foundation; either
**    version 3 of the License, or (at your option) any later version.
**
**    This library is distributed in the hope that it will be useful,
**    but WITHOUT ANY WARRANTY; without even the implied warranty of
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
**    Lesser General Public License for more details.
**
**    You should have received a copy of the GNU Lesser General Public
**    License along with this library; if not, write to the Free Software
**    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*/

package org.systemsbiology.util;


import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

/**
 * Author: anorberg
 * Created on: Nov 9, 2010
 */

/**
 * Filter class that represents a set of filters (a HashSet, specifically; it plans to hash by object handle)
 * and accepts elements if they pass any of them.
 * @param <T> Element type for items to be filtered.
 */
public class DisjunctionFilter<T>  extends HashSet<Filter<T>> implements Filter<T>{
	private static final long serialVersionUID = -5730054063235747258L;

	/**
	 * Constructs a DisjunctionFilter initially containing no filters.
	 */
	public DisjunctionFilter(){
        super();
    }

	/**
	 * Constructs a DisjunctionFilter initially containing filters specified by an Iterator.
	 * @param startingSet Filters to include in the set.
	 */
    public DisjunctionFilter(Iterator<? extends Filter<T>> startingSet){
        super();
        while(startingSet.hasNext()){
            add(startingSet.next());
        }
    }

    /**
     * Constructs a DisjunctionFilter initially containing filters specified in a Collection.
     * @param startingSet Filters to include in the set. This collection is not modified, and
     * 		  subsequent modifications to it are not reflected in the DisjunctionFilter.
     */
    public DisjunctionFilter(Collection<? extends Filter<T>> startingSet){
        super(startingSet);
    }

    /**
     * Constructs a DisjunctionFilter initially containing filters specified in an array.
     * @param startingSet Filters to include in the set.
     */
    public DisjunctionFilter(Filter<T>[] startingSet){
        super(Arrays.asList(startingSet));
    }

    /**
     * Accepts an object if it passes <i>any</i> of the filters included (<i>any</i> of them
     * returns true from their accept method). DisjunctionFilter performs an early-out, and
     * will therefore call filters only until one of them returns true or all filters have been
     * called once (at which point it will stop and return false). No specific order is guaranteed.
     * <p>
     * If the DisjunctionFilter is empty (contains zero filters), this method returns false,
     * because nothing has accepted the item.
     */
    public boolean accept(T item){
        for(Filter<T> foo : this){
            if(foo.accept(item)){return true;}
        }
        return false;
    }

}

